package com.demo.java.OD251_300.OD282;

import java.util.*;

/**
 * @author bug菌
 * @Source 公众号：猿圈奇妙屋
 * @des： 【快速开租建站】问题
 * @url： https://blog.csdn.net/weixin_43970743/article/details/146079374
 */
public class OdMain {
    public static int solveMethod(int[][] relations, int taskNum) {
        // 保存每个任务的后继任务列表
        Map<Integer, List<Integer>> next = new HashMap<>();
        // 保存每个任务的入度
        int[] inDegree = new int[taskNum];
        // 记录每个任务的最早开始时间
        int[] earliestStartTime = new int[taskNum];

        // 建立图和入度数组
        for (int[] relation : relations) {
            int a = relation[0], b = relation[1];
            // 添加后继任务
            next.computeIfAbsent(a, k -> new ArrayList<>()).add(b);
            // 更新入度
            inDegree[b]++;
        }

        // 存储队列，初始将入度为 0 的任务加入队列
        Queue<int[]> queue = new LinkedList<>();
        int t = 1;  // 时间从 1 开始
        for (int i = 0; i < taskNum; i++) {
            if (inDegree[i] == 0) {
                queue.offer(new int[]{i, t});
            }
        }

        while (!queue.isEmpty()) {
            // 弹出队首任务
            int[] taskAndTime = queue.poll();
            int task = taskAndTime[0], time = taskAndTime[1];
            // 更新该任务的最早开始时间
            earliestStartTime[task] = time;
            // 处理后继任务
            if (next.containsKey(task)) {
                for (int nxt : next.get(task)) {
                    inDegree[nxt]--;
                    if (inDegree[nxt] == 0) {
                        // 后继任务入度为 0，加入队列
                        t = time + 1;
                        queue.offer(new int[]{nxt, t});
                    }
                }
            }
        }

        // 返回任务完成所需的最短时间
        int maxTime = 0;
        for (int i = 0; i < taskNum; i++) {
            maxTime = Math.max(maxTime, earliestStartTime[i]);
        }
        return maxTime;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int taskNum = sc.nextInt(), relationsNum = sc.nextInt();
        int[][] relations = new int[relationsNum][2];
        for (int i = 0; i < relationsNum; i++) {
            relations[i][0] = sc.nextInt();
            relations[i][1] = sc.nextInt();
        }
        System.out.println(solveMethod(relations, taskNum));
    }
}